package com.genexususa.eo.bing.connection;

import com.genexususa.eo.bing.CampaignManagementServiceClasses.*;
import com.genexususa.eo.bing.CampaignManagementServiceClasses.AdApiFaultDetail;
import com.genexususa.eo.bing.CustomerManagementServiceClasses.*;
import com.genexususa.eo.bing.CustomerManagementServiceClasses.Address;
import com.genexususa.eo.bing.data.GxException;
import com.genexususa.eo.bing.data.GxItemException;
import com.genexususa.eo.bing.data.Info;
import com.genexususa.eo.bing.data.Util;
import com.genexususa.eo.bing.data.results.*;
import com.genexususa.eo.bing.data.wsSubclasses.GxAccount;
import com.genexususa.eo.bing.data.wsSubclasses.GxAccountAnalyticsType;
import com.genexususa.eo.google.data.GA_Result;
import com.genexususa.eo.google.data.GA_ResultItem;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.rpc.ServiceException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Properties;

public class AccountManager {

    private static String url = "https://clientcenter.api.sandbox.bingads.microsoft.com/Api/CustomerManagement/v9/CustomerManagementService.svc?wsdl";
    private static String namespace = null;

    public AccountManager() {
    }

    public String addAccount(){

        return "";
    }


    public void getCustomerInfo(){
        BasicHttpBinding_ICustomerManagementServiceStub stub = null;

        try{

            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("reportingNamespace");
            String url = properties.get("accountsURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");
            int retries = Integer.parseInt(properties.get("retries"));

            Long wait = Long.parseLong(properties.get("waitForDownload"));

            CustomerManagementServiceLocator locator = new CustomerManagementServiceLocator();
            locator.setBasicHttpBinding_ICustomerManagementServiceEndpointAddress(url);
            namespace = locator.getServiceName().getNamespaceURI();
            stub = (BasicHttpBinding_ICustomerManagementServiceStub)locator.getBasicHttpBinding_ICustomerManagementService();

            stub.clearHeaders();

            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            //stub.setHeader(namespace, "CustomerAccountId", Long.parseLong(customerAccount));
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            GetCustomersInfoRequest request = new GetCustomersInfoRequest();

            request.setApplicationScope(ApplicationType.Advertiser);
            request.setCustomerNameFilter("");
            request.setTopN(1000);

            CustomerInfo[] customerInfo = stub.getCustomersInfo(request).getCustomersInfo();

            for (CustomerInfo ci : customerInfo){

                System.out.println(ci.getName() + ": " + ci.getId());
            }




        } catch (ServiceException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (ApiFault apiFault) {
            apiFault.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (com.genexususa.eo.bing.CustomerManagementServiceClasses.AdApiFaultDetail adApiFaultDetail) {
            adApiFaultDetail.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (RemoteException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public void getAccountsInfo(){
        BasicHttpBinding_ICustomerManagementServiceStub stub = null;

        try{

            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("reportingNamespace");
            String url = properties.get("accountsURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");
            int retries = Integer.parseInt(properties.get("retries"));

            Long wait = Long.parseLong(properties.get("waitForDownload"));

            CustomerManagementServiceLocator locator = new CustomerManagementServiceLocator();
            locator.setBasicHttpBinding_ICustomerManagementServiceEndpointAddress(url);
            namespace = locator.getServiceName().getNamespaceURI();
            stub = (BasicHttpBinding_ICustomerManagementServiceStub)locator.getBasicHttpBinding_ICustomerManagementService();

            stub.clearHeaders();

            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            //stub.setHeader(namespace, "CustomerAccountId", Long.parseLong(customerAccount));
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            GetAccountsInfoRequest request = new GetAccountsInfoRequest();

            AccountInfo[] accountsInfo = stub.getAccountsInfo(request).getAccountsInfo();

           // String res = "";
            for (AccountInfo ai : accountsInfo){

                System.out.println(ai.getName() +  ": " + ai.getId() + " - " +  ai.getNumber() +  " - " + ai.getAccountLifeCycleStatus().getValue());
                //res += ai.getId() + ";";
            }

           //System.out.println(res);







        } catch (ServiceException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (ApiFault apiFault) {
            apiFault.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (com.genexususa.eo.bing.CustomerManagementServiceClasses.AdApiFaultDetail adApiFaultDetail) {
            adApiFaultDetail.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (RemoteException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public Account getAccount(Long accountId){
        BasicHttpBinding_ICustomerManagementServiceStub stub = null;

        try{

            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("reportingNamespace");
            String url = properties.get("accountsURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");
            int retries = Integer.parseInt(properties.get("retries"));

            Long wait = Long.parseLong(properties.get("waitForDownload"));

            CustomerManagementServiceLocator locator = new CustomerManagementServiceLocator();
            locator.setBasicHttpBinding_ICustomerManagementServiceEndpointAddress(url);
            namespace = locator.getServiceName().getNamespaceURI();
            stub = (BasicHttpBinding_ICustomerManagementServiceStub)locator.getBasicHttpBinding_ICustomerManagementService();

            stub.clearHeaders();

            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", accountId);
            //stub.setHeader(namespace, "ApplicationToken", applicationToken);

            GetAccountRequest request = new GetAccountRequest();

            request.setAccountId(accountId);

            Account account = stub.getAccount(request).getAccount();

            return account;



        } catch (ServiceException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (ApiFault apiFault) {
            apiFault.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (com.genexususa.eo.bing.CustomerManagementServiceClasses.AdApiFaultDetail adApiFaultDetail) {
            adApiFaultDetail.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (RemoteException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return null;
    }

    public String createAccount(/*long customerAccountId, */String xml){
        BasicHttpBinding_ICustomerManagementServiceStub stub = null;
        GA_Result res = new GA_Result();
        String result = "";

        try{

            Util util = new Util();

            Document doc = util.loadXMLFromString(xml);

            HashMap<String, String> properties = Info.getBingProperties();
            //String namespace = properties.get("reportingNamespace");
            String url = properties.get("accountsURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");
            int retries = Integer.parseInt(properties.get("retries"));

            Long wait = Long.parseLong(properties.get("waitForDownload"));

            CustomerManagementServiceLocator locator = new CustomerManagementServiceLocator();
            locator.setBasicHttpBinding_ICustomerManagementServiceEndpointAddress(url);
            namespace = locator.getServiceName().getNamespaceURI();
            stub = (BasicHttpBinding_ICustomerManagementServiceStub)locator.getBasicHttpBinding_ICustomerManagementService();

            stub.clearHeaders();

            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            //stub.setHeader(namespace, "CustomerAccountId", Long.parseLong(customerAccount));
            stub.setHeader(namespace, "ApplicationToken", applicationToken);
            XPathFactory factory = XPathFactory.newInstance();
            XPath xpath = factory.newXPath();
            XPathExpression expr = xpath.compile("//Bing_AccountCollection.SignupCustomer");

            Object accountsNodes = expr.evaluate(doc, XPathConstants.NODESET);
            NodeList accounts = (NodeList) accountsNodes;

            if (accounts.getLength() > 0){
                for (int i = 0; i < accounts.getLength(); i++) {
                    GA_ResultItem resultItem = new GA_ResultItem();
                    Node n = accounts.item(i);
                    NodeList children = n.getChildNodes();
                    if (children.getLength() > 0) {
                        SignupCustomerRequest request = new SignupCustomerRequest();
                        for (int j = 0; j < children.getLength(); j++) {
                            if (children.item(j).getNodeName().equalsIgnoreCase("Customer")) {
                                request.setCustomer(parseCustomer(children.item(j)));
                            }

                            if (children.item(j).getNodeName().equalsIgnoreCase("Account")) {
                                request.setAccount(parseAccount(children.item(j)));
                                NodeList accountChildren = children.item(j).getChildNodes();
                                if (accountChildren.getLength() > 0){
                                    for (int z = 0; z < accountChildren.getLength(); z++) {
                                        if (accountChildren.item(z).getNodeName().equalsIgnoreCase("GxAccountId")) {
                                            resultItem.AccountGxId = Long.parseLong(accountChildren.item(z).getTextContent());
                                        }
                                    }
                                }
                            }

                            System.out.println(children.item(j).getNodeName());
                        }

                        //request.setApplicationScope(ApplicationType.Advertiser);
                        request.setParentCustomerId(Long.parseLong(customerId));
                        SignupCustomerResponse response = stub.signupCustomer(request);

                        resultItem.AccountId = response.getAccountId();
                        resultItem.AccountNumber = response.getAccountNumber();
                        //resultItem.CreateTime = response.getCreateTime().getTime().toString();
                        resultItem.CustomerId = response.getCustomerId();
                        resultItem.CustomerNumber = response.getCustomerNumber();

                        res.Items.add(resultItem);

                    }
                }
            }
        } catch (ServiceException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

            GA_ResultItem item = new GA_ResultItem(e);
            res.Items.add(item);

        } catch (ApiFault apiFault) {
            apiFault.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            GA_ResultItem item = new GA_ResultItem(apiFault);
            res.Items.add(item);
        } catch (com.genexususa.eo.bing.CustomerManagementServiceClasses.AdApiFaultDetail adApiFaultDetail) {
            adApiFaultDetail.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            GA_ResultItem item = new GA_ResultItem(adApiFaultDetail);
            res.Items.add(item);
        } catch (RemoteException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            GA_ResultItem item = new GA_ResultItem(e);
            res.Items.add(item);
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            GA_ResultItem item = new GA_ResultItem(e);
            res.Items.add(item);
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            GA_ResultItem item = new GA_ResultItem(e);
            res.Items.add(item);
        }

        try {

            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class);

            Marshaller marshallerObj = contextObj.createMarshaller();
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(res, sw);
            result = sw.getBuffer().toString();
            System.out.println(result);


        } catch (Exception exc) {
            exc.printStackTrace();
            result = exc.getMessage();
        }

        return result;
    }

    private AdvertiserAccount parseAccount(Node item) {

        NodeList children = item.getChildNodes();

        AdvertiserAccount account = new AdvertiserAccount();
        //account.setAccountType(AccountType.Advertiser);

        if (children.getLength() > 0){
            for (int i = 0; i < children.getLength(); i++) {
                /*if (children.item(i).getNodeName().equalsIgnoreCase("AccountType")) {
                    account.setAccountType(AccountType.Advertiser);
                } */
               /* if (children.item(i).getNodeName().equalsIgnoreCase("BillToCustomerId")) {
                    account.setBillToCustomerId(Long.parseLong(children.item(i).getTextContent()));
                }   */
                /*if (children.item(i).getNodeName().equalsIgnoreCase("CountryCode")) {
                    account.setCountryCode(children.item(i).getTextContent());
                }    */
                if (children.item(i).getNodeName().equalsIgnoreCase("CurrencyType")) {
                    account.setCurrencyType(CurrencyType.fromString(children.item(i).getTextContent()));
                }
                /*if (children.item(i).getNodeName().equalsIgnoreCase("AccountFinancialStatus")) {
                    account.setAccountFinancialStatus(AccountFinancialStatus.fromString(children.item(i).getTextContent()));
                }   */
                if (children.item(i).getNodeName().equalsIgnoreCase("Id")) {
                    if (children.item(i).getTextContent() != ""){
                        account.setId(Long.parseLong(children.item(i).getTextContent()));
                    }
                }
               /* if (children.item(i).getNodeName().equalsIgnoreCase("Language")) {
                    account.setLanguage(LanguageType.fromString(children.item(i).getTextContent()));
                }*/
                if (children.item(i).getNodeName().equalsIgnoreCase("Name")) {
                    account.setName(children.item(i).getTextContent());
                }
                /*if (children.item(i).getNodeName().equalsIgnoreCase("Number")) {
                    account.setNumber(children.item(i).getTextContent());
                }*/
                /*if (children.item(i).getNodeName().equalsIgnoreCase("ParentCustomerId")) {
                    account.setParentCustomerId(Long.parseLong(children.item(i).getTextContent()));
                }           */
                /*if (children.item(i).getNodeName().equalsIgnoreCase("PaymentMethodId")) {
                    account.setPaymentMethodId(Long.parseLong(children.item(i).getTextContent()));
                }
                if (children.item(i).getNodeName().equalsIgnoreCase("PaymentMethodType")) {
                    account.setPaymentMethodType(PaymentMethodType.fromString(children.item(i).getTextContent()));
                }   */
                /*if (children.item(i).getNodeName().equalsIgnoreCase("AccountLifeCycleStatus")) {
                    account.setAccountLifeCycleStatus(AccountLifeCycleStatus.fromString(children.item(i).getTextContent()));
                } */
                /*if (children.item(i).getNodeName().equalsIgnoreCase("TimeZone")) {
                    account.setTimeZone(TimeZoneType.fromString(children.item(i).getTextContent()));
                }
                if (children.item(i).getNodeName().equalsIgnoreCase("PauseReason")) {
                    //account.setPauseReason(children.item(i).getTextContent());
                } */
            }
        }

        return account;
    }

    private Customer parseCustomer(Node item) {
        NodeList children = item.getChildNodes();

        Customer customer = new Customer();

        if (children.getLength() > 0){
            for (int i = 0; i < children.getLength(); i++) {
                if (children.item(i).getNodeName().equalsIgnoreCase("CustomerAddress")) {
                    customer.setCustomerAddress(parseCustomerAddress(children.item(i)));
                }
                /*if (children.item(i).getNodeName().equalsIgnoreCase("CustomerFinancialStatus")){
                    customer.setCustomerFinancialStatus(CustomerFinancialStatus.fromString(children.item(i).getTextContent()));
                } */
                if (children.item(i).getNodeName().equalsIgnoreCase("Id")){
                    customer.setId(Long.parseLong(children.item(i).getTextContent()));
                }
                if (children.item(i).getNodeName().equalsIgnoreCase("Industry")){
                    customer.setIndustry(Industry.fromString(children.item(i).getTextContent()));
                }
                if (children.item(i).getNodeName().equalsIgnoreCase("MarketCountry")){
                    customer.setMarketCountry(children.item(i).getTextContent());
                }
                if (children.item(i).getNodeName().equalsIgnoreCase("MarketLanguage")){
                    customer.setMarketLanguage(LanguageType.fromString(children.item(i).getTextContent()));
                }
                if (children.item(i).getNodeName().equalsIgnoreCase("Name")){
                    customer.setName(children.item(i).getTextContent());
                }
                /*if (children.item(i).getNodeName().equalsIgnoreCase("ServiceLevel")){
                    customer.setServiceLevel(ServiceLevel.fromString(children.item(i).getTextContent()));
                }  */
                /*if (children.item(i).getNodeName().equalsIgnoreCase("CustomerLifeCycleStatus")){
                    customer.setCustomerLifeCycleStatus(CustomerLifeCycleStatus.fromString(children.item(i).getTextContent()));
                } */
                /*if (children.item(i).getNodeName().equalsIgnoreCase("Number")){
                    customer.setNumber(children.item(i).getTextContent());
                }  */

            }
        }

        return customer;
    }

    private Address parseCustomerAddress(Node item) {
        NodeList children = item.getChildNodes();
        Address address = new Address();

        for (int i = 0; i < children.getLength(); i++) {
            if (children.item(i).getNodeName().equalsIgnoreCase("City")){
                address.setCity(children.item(i).getTextContent());
            }
            if(children.item(i).getNodeName().equalsIgnoreCase("CountryCode")){
                address.setCountryCode(children.item(i).getTextContent());
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("Line1")){
                if (children.item(i).getTextContent() != ""){
                    address.setLine1(children.item(i).getTextContent());
                }
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("Line2")){
                if (children.item(i).getTextContent() != ""){
                    address.setLine2(children.item(i).getTextContent());
                }
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("Line3")){
                if (children.item(i).getTextContent() != ""){
                    address.setLine3(children.item(i).getTextContent());
                }
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("Line4")){
                if (children.item(i).getTextContent() != ""){
                    address.setLine4(children.item(i).getTextContent());
                }
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("PostalCode")){
                address.setPostalCode(children.item(i).getTextContent());
            }
            if (children.item(i).getNodeName().equalsIgnoreCase("StateOrProvince")){
                address.setStateOrProvince(children.item(i).getTextContent());
            }
        }

        return address;
    }


    public String addAccounts(long customerAccountId, String accountsXML) {
        ICustomerManagementService customerManagement = null;
        CustomerManagementServiceLocator customerServiceLocator = null;
        BasicHttpBinding_ICustomerManagementServiceStub stub = null;
        AddAccountRequest addAccountRequest = null;
        AddAccountResponse addAccountResponse = null;
        GxIdResults result = null;
        String trackingId = "";
        Util util = new Util();
        Account[] accounts = null;
        try {

            HashMap<String, String> properties = Info.getBingProperties();
            //String namespace = properties.get("namespace");
            //String url = properties.get("url");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");

            /*
            Properties properties = new Properties();
            properties.load(new FileInputStream("bing.properties"));
            String namespace = properties.getProperty("namespace");
            String url = properties.getProperty("url");
              */

            customerServiceLocator = new CustomerManagementServiceLocator();
            customerServiceLocator.setBasicHttpBinding_ICustomerManagementServiceEndpointAddress(url);
            customerManagement = customerServiceLocator.getBasicHttpBinding_ICustomerManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICustomerManagementServiceStub) customerManagement;
            namespace = customerServiceLocator.getServiceName().getNamespaceURI();

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            addAccountRequest = new AddAccountRequest();
            // Parse accounts from XML
            accounts = util.accountsFromXML(accountsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            addAccountRequest.setAccount(accounts[0]);

            // Call WS
            addAccountResponse = customerManagement.addAccount(addAccountRequest); // RemoteException, ApiFaultDetail, AdApiFaultDetail

            // Call succeeded with no errors

            // Create the return object
            trackingId = stub.getResponseHeader(namespace, "TrackingId").getValue();
            long[] accountIds = new long[1];
            accountIds[0] = addAccountResponse.getAccountId();
            result = new GxIdResults(trackingId, accountIds.length);
            for (int i=0; i<accountIds.length; i++) {
                result.addResult(i, new GxIdResult(((GxAccount)accounts[i]).getGxId(), accountIds[i]));
            }
        } catch (ServiceException e) { // BEFORE CALL
            result = new GxIdResults(trackingId);
            result.addServiceExceptionError(e);
        } catch (IllegalArgumentException e) { // BEFORE CALL
            result = new GxIdResults(trackingId);
            result.addIllegalArgumentExceptionError(e);
        } catch (GxException e) { // BEFORE CALL
            result = new GxIdResults(trackingId, e.getExceptions().length);
            for (int i=0; i<e.getExceptions().length; i++) {
                result.addResult(i, new GxIdResult());
            }
            result.addGxExceptionError(e);
        } catch (ParserConfigurationException e) { // BEFORE CALL
            result = new GxIdResults(trackingId);
            result.addParserConfigurationExceptionError(e);
        } catch (SAXException e) { // BEFORE CALL
            result = new GxIdResults(trackingId);
            result.addSAXExceptionError(e);
        } catch (ApiFaultDetail fault) { // IN CALL
            trackingId = fault.getTrackingId();
            if (fault.getBatchErrors().length > 0) {
                result = new GxIdResults(trackingId, accounts.length);
                for (int i=0; i<accounts.length; i++) {
                    result.addResult(i, new GxIdResult(((GxAccount)accounts[i]).getGxId()));
                }
            } else {
                result = new GxIdResults(trackingId);
            }
            result.addApiFaultDetailError(fault);
        } catch (AdApiFaultDetail fault) { // IN CALL
            trackingId = fault.getTrackingId();
            result = new GxIdResults(trackingId);
            result.addAdApiFaultDetailError(fault);
        } catch (RemoteException e) { // IN CALL
            result = new GxIdResults(trackingId);
            result.addRemoteExceptionError(e);
        } catch (IOException e) { // BEFORE CALL
            result = new GxIdResults(trackingId);
            result.addIOExceptionError(e);
        }

        String returnMessage = null;
        // GxIdResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GxIdResults.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }

    /*
    public String setAnalyticsType(String userName, String password, String developerToken, long customerId, long customerAccountId, String applicationToken, String accountAnalyticsTypesXML) {
        String namespace = Info.namespace;
        String url = Info.url;
        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        SetAnalyticsTypeRequest setAnalyticsTypeRequest = null;
        GxTrackingIdResults result = null;
        String trackingId = "";
        Util util = new Util();
        AccountAnalyticsType[] accountAnalyticsTypes = null;
        AccountAnalyticsType[] accountAnalyticsTypeToSend = null;
        try {
            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Parse accountAnalyticsTypes from XML
            accountAnalyticsTypes = util.accountAnalyticsTypesFromXML(accountAnalyticsTypesXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            if (accountAnalyticsTypes.length == 0) {
                throw new GxItemException("No AccountAnalyticsTypes were found");
            }
            result = new GxTrackingIdResults(accountAnalyticsTypes.length);
            for (int i=0; i<accountAnalyticsTypes.length; i++) {
                result.addResult(i, new GxTrackingIdResult());
            }

            for (int j=0; j<accountAnalyticsTypes.length; j++) {
                // Set body parameters
                setAnalyticsTypeRequest = new SetAnalyticsTypeRequest();
                accountAnalyticsTypeToSend = new AccountAnalyticsType[1];
                accountAnalyticsTypeToSend[0] = accountAnalyticsTypes[j];
                setAnalyticsTypeRequest.setAccountAnalyticsTypes(accountAnalyticsTypeToSend);

                try {
                    // Call WS
                    campaignManagement.setAnalyticsType(setAnalyticsTypeRequest); // RemoteException, ApiFaultDetail, AdApiFaultDetail

                    // Call succeeded with no errors

                    // Create the return object
                    trackingId = stub.getResponseHeader(namespace, "TrackingId").getValue();
                    result.getTrackingIdResultCollection()[j].setSpecificTrackingId(trackingId);
                    result.getTrackingIdResultCollection()[j].setGxId(((GxAccountAnalyticsType)accountAnalyticsTypes[j]).getGxAccountId());
                    result.getTrackingIdResultCollection()[j].setBingId(accountAnalyticsTypes[j].getAccountId());
                } catch (ApiFaultDetail fault) { // IN CALL
                    trackingId = fault.getTrackingId();
                    result.getTrackingIdResultCollection()[j].setGxId(((GxAccountAnalyticsType)accountAnalyticsTypes[j]).getGxAccountId());
                    result.getTrackingIdResultCollection()[j].setSpecificTrackingId(trackingId);
                    result.getTrackingIdResultCollection()[j].addApiFaultDetailError(fault);
                    result.setError();
                } catch (AdApiFaultDetail fault) { // IN CALL
                    trackingId = fault.getTrackingId();
                    result.getTrackingIdResultCollection()[j].setGxId(((GxAccountAnalyticsType)accountAnalyticsTypes[j]).getGxAccountId());
                    result.getTrackingIdResultCollection()[j].setSpecificTrackingId(trackingId);
                    result.getTrackingIdResultCollection()[j].addAdApiFaultDetailError(fault);
                    result.setError();
                } catch (RemoteException e) { // IN CALL
                    result.getTrackingIdResultCollection()[j].addRemoteExceptionError(e);
                    result.setError();
                }
            }
        } catch (ServiceException e) { // BEFORE CALL
            result = new GxTrackingIdResults();
            result.addServiceExceptionError(e);
        } catch (IllegalArgumentException e) { // BEFORE CALL
            result = new GxTrackingIdResults();
            result.addIllegalArgumentExceptionError(e);
        } catch (GxException e) { // BEFORE CALL
            result = new GxTrackingIdResults(e.getExceptions().length);
            for (int i=0; i<e.getExceptions().length; i++) {
                result.addResult(i, new GxTrackingIdResult());
            }
            result.addGxExceptionError(e);
        } catch (ParserConfigurationException e) { // BEFORE CALL
            result = new GxTrackingIdResults();
            result.addParserConfigurationExceptionError(e);
        } catch (SAXException e) { // BEFORE CALL
            result = new GxTrackingIdResults();
            result.addSAXExceptionError(e);
        } catch (GxItemException e) { // BEFORE CALL
            result = new GxTrackingIdResults();
            result.addGxItemExceptionError(e);
        } catch (IOException e) { // BEFORE CALL
            result = new GxTrackingIdResults();
            result.addIOExceptionError(e);
        }

        String returnMessage = null;
        // GxTrackingIdResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GxTrackingIdResults.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }
    */
}
